﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using SmartWMS.Domain.Base;
using SmartWMS.Domain.SystemSet;
using SmartWMS.EntityFramework;
namespace SmartWMS.Server.Repository
{
    public class Repository<T> : IRepository<T> where T : KeyEntity
    {
        private readonly SmartWMSContext _dbContext;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public Repository(SmartWMSContext dbContext, IHttpContextAccessor httpContextAccessor)
        {
            _dbContext = dbContext;
            _httpContextAccessor = httpContextAccessor;
        }
        public async Task<List<T>> GetAllListAsync()
        {
            return await _dbContext.Set<T>().ToListAsync();
        }

        public IQueryable<T> GetListQuery()
        {
            return _dbContext.Set<T>().AsQueryable();
        }

        public int GetCount()
        {
            return _dbContext.Set<T>().Count();
        }

        public async Task<T> GetEntityByIdAsync(KeyEntity key)
        {
            return await _dbContext.FindAsync<T>(key.Id);
        }

        /// <summary>
        /// 单条添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> InsertAsync(T entity)
        {
            //SetCreator(entity, GetUserId());
            _dbContext.Set<T>().Add(entity);

            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> InsertAsync(List<T> values)
        {
            if (values == null || values.Count == 0)
            {
                return default;
            }

            await _dbContext.Set<T>().AddRangeAsync(values);
            int i = await _dbContext.SaveChangesAsync();
            return i;
        }

        /// <summary>
        /// 单条编辑
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> UpdateAsync(T entity)
        {
            _dbContext.Entry(entity).State = EntityState.Modified;
            return await _dbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 批量编辑
        /// </summary>
        /// <param name="entities">要编辑的实体集合</param>
        /// <returns>异步操作结果</returns>
        public async Task<int> UpdateRangeAsync(List<T> entities)
        {
            if (entities == null || !entities.Any())
            {
                return 0;
            }

            foreach (var entity in entities)
            {
                _dbContext.Entry(entity).State = EntityState.Modified;
            }

            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 单条删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<int> DeleteByIdAsync(KeyEntity key)
        {
            var entity = await _dbContext.Set<T>().FindAsync(key.Id);
            if (entity != null)
            {
                _dbContext.Entry(entity).State = EntityState.Deleted;
                return await _dbContext.SaveChangesAsync();
            }

            return default;
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> DeleteAsync(List<T> values)
        {
            //批量删除
            _dbContext.Set<T>().RemoveRange(values);
            int i = await _dbContext.SaveChangesAsync();
            return i;
        }

        /// <summary>
        /// 执行sql语句，返回受影响行数
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int ExecuteSql(string sql)
        {
            return _dbContext.Database.ExecuteSqlRaw(sql);
        }

        /// <summary>
        /// 使用SQL脚本查询
        /// </summary>
        /// <typeparam name="T"> T为数据库实体</typeparam>
        /// <returns></returns>
        public IQueryable<T> FromSql(string sql, params object[] parameters)
        {
            if (parameters == null)
                return _dbContext.Set<T>().FromSqlRaw(sql);
            else
                return _dbContext.Set<T>().FromSqlRaw(sql, parameters);
        }

        /// <summary>
        /// 设置创建用户的信息
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="userId"></param>
        private void SetCreator(T entity, int userId)
        {
            if (entity != null)
            {
                if (entity is BaseEntity)
                {
                    var baseEntity = entity as BaseEntity;
                    baseEntity.Creator = userId;
                    baseEntity.CreateTime = DateTime.Now;
                }
            }
        }

        /// <summary>
        /// 设置编辑用户信息
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="userId"></param>
        private void SetEditor(T entity, int userId)
        {
            if (entity != null)
            {
                if (entity is BaseEntity)
                {
                    var baseEntity = entity as BaseEntity;
                    baseEntity.Editor = userId;
                    baseEntity.EditTime = DateTime.Now;
                }
            }
        }

        /// <summary>
        /// 设置删除用户信息
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="userId"></param>
        private void SetDeletor(T entity, int userId)
        {
            if (entity != null)
            {
                if (entity is BaseEntity)
                {
                    var baseEntity = entity as BaseEntity;
                    baseEntity.Deletor = userId;
                    baseEntity.DeleteTime = DateTime.Now;
                    baseEntity.IsDelete = true;
                    _dbContext.Set<T>().Update(entity);
                }
                else
                {
                    _dbContext.Set<T>().Remove(entity);
                }
            }
        }

        /// <summary>
        /// 获取当前登录用户信息
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private int GetUserId() =>
             Convert.ToInt32(_httpContextAccessor.HttpContext.User.Claims
             .FirstOrDefault(c => c.Type == JwtRegisteredClaimNames.Jti)?.Value
             ?? throw new Exception("用户未登录"));

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="staff"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public async Task<int> ResetPasswordAsync(Staff staff, string newPassword)
        {
            staff.StaffPwd = newPassword;
            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 单个删除逻辑删除
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<int> DelState(KeyEntity key)
        {
            var list = _dbContext.Set<Role>().FirstOrDefault(t => t.Id == key.Id);

            if (list != null)
            {
                list.Enable = !list.Enable;
            }

            return await _dbContext.SaveChangesAsync();

        }

        /// <summary>
        /// 添加角色权限
        /// </summary>
        /// <param name="rid"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
        public async Task<int> AddRolePermissionAsync(int rid, string pid)
        {
            using (var tran = _dbContext.Database.BeginTransaction())
            {
                try
                {
                    var list = _dbContext.Set<RolePermissions>().Where(t => t.RoleID == rid).ToList();
                    if (list != null)
                    {
                        _dbContext.Set<RolePermissions>().RemoveRange(list);
                        _dbContext.SaveChanges();
                    }
                    var PermissionId = pid.Split(',');
                    List<RolePermissions> rolePermissions = new List<RolePermissions>();
                    foreach (var item in PermissionId)
                    {
                        var rolePermission = new RolePermissions();
                        rolePermission.RoleID = rid;
                        rolePermission.PermissionsID = Convert.ToInt32(item);
                        rolePermissions.Add(rolePermission);

                    }
                    await _dbContext.Set<RolePermissions>().AddRangeAsync(rolePermissions);
                    tran.Commit();
                    return await _dbContext.SaveChangesAsync();

                }
                catch (Exception)
                {
                    tran.Rollback();
                    throw;
                }
            }
        }

        /// <summary>
        /// 反填角色权限（树形）
        /// </summary>
        /// <param name="rid"></param>
        /// <returns></returns>
        public async Task<List<int>> SelRolePermissionAsync(int rid)
        {
            var list = _dbContext.Set<RolePermissions>().Where(t => t.RoleID == rid).ToList();
            List<int> ints = new List<int>();
            foreach (var item in list)
            {
                ints.Add(item.PermissionsID);
            }
            return await Task.FromResult(ints);
        }
    }
}
